/**
 * PostClassifier.java
 * Implements a classifier that, when given a particular post with relevant 
 * information, returns whether said post is about experience or about an 
 * advice.
 */
package edu.illinois.cs.mmak4.cs410;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Iterator;

import cc.mallet.classify.Classifier;
import cc.mallet.pipe.iterator.StringArrayIterator;
import cc.mallet.types.Instance;
import cc.mallet.types.Labeling;

/**
 * @author mmak4
 * 
 */
public class PostClassifier {
	Classifier classifier;

	/**
	 * We need a file object to the serialized version of the classifier,
	 * whatever it is.
	 * 
	 * @param serializedClassifier
	 */
	public PostClassifier(File serializedClassifier) {
		super();
		try {
			this.classifier = this.loadClassifier(serializedClassifier);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public String classify(String post) {
		// Break post into sentences (just use '.' to split)
		String[] sentences = post.split("[.]");
		double[] vote = new double[3];

		// System.out.println(post);
		// System.out.println(sentences.length);

		// Set up the iterator
		Iterator<Instance> sentenceIterator = new StringArrayIterator(sentences);
		Iterator<Instance> iterator = classifier.getInstancePipe()
				.newIteratorFrom(sentenceIterator);

		classifier.getInstancePipe().getDataAlphabet().stopGrowth();
		classifier.getInstancePipe().getTargetAlphabet().stopGrowth();

		// For each sentence, use the sentence classifier to get distribution. 0
		// is nonsense, 1 is experience, 2 is advice.
		while (iterator.hasNext()) {
			Instance instance = iterator.next();

			// Run the classifier and add the votes up
			Labeling labeling = classifier.classify(instance).getLabeling();
			vote[Integer.parseInt(labeling.getLabelAtRank(0).toString())] += labeling.getBestValue(); 
			
			/*
			for (int location = 0; location < labeling.numLocations(); location++) {
				vote[Integer.parseInt(labeling.labelAtLocation(location)
						.toString())] += Math.log(labeling.valueAtLocation(location));
			}*/
		}

		// Count the votes and return winner as label
		int max_index = -1;
		double max_sum = -1.0;
		for (int i = 0; i < vote.length; i++) {
			if (vote[i] > max_sum) {
				max_sum = vote[i];
				max_index = i;
			}
		}

		switch (max_index) {
		case 0:
			return "Neither";
		case 1:
			return "Experience";
		case 2:
			return "Advice";
		}
		return "Neither";
	}

	private Classifier loadClassifier(File serializedFile)
			throws FileNotFoundException, IOException, ClassNotFoundException {

		// The standard way to save classifiers and Mallet data
		// for repeated use is through Java serialization.
		// Here we load a serialized classifier from a file.

		Classifier classifier;

		ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
				serializedFile));
		classifier = (Classifier) ois.readObject();
		ois.close();

		return classifier;
	}
}
